package utils

import "reflect"

// utils list set map 等常用数据集合的工具类

// 求并集
func UnionForString(slice1, slice2 []string) []string {
	m := make(map[string]int)
	for _, v := range slice1 {
		m[v]++
	}

	for _, v := range slice2 {
		times, _ := m[v]
		if times == 0 {
			slice1 = append(slice1, v)
		}
	}
	return slice1
}

// 求交集
func IntersectForString(slice1, slice2 []string) []string {
	m := make(map[string]int)
	nn := make([]string, 0)
	for _, v := range slice1 {
		m[v]++
	}

	for _, v := range slice2 {
		times, _ := m[v]
		if times == 1 {
			nn = append(nn, v)
		}
	}
	return nn
}

// 求差集 slice1-并集
func DifferenceForString(slice1, slice2 []string) []string {
	m := make(map[string]int)
	nn := make([]string, 0)
	inter := IntersectForString(slice1, slice2)
	for _, v := range inter {
		m[v]++
	}

	for _, value := range slice1 {
		times, _ := m[value]
		if times == 0 {
			nn = append(nn, value)
		}
	}
	return nn
}

// 求并集
func UnionForInt(slice1, slice2 []int) []int {
	m := make(map[int]int)
	for _, v := range slice1 {
		m[v]++
	}

	for _, v := range slice2 {
		times, _ := m[v]
		if times == 0 {
			slice1 = append(slice1, v)
		}
	}
	return slice1
}

// 求交集
func IntersectForInt(slice1, slice2 []int) []int {
	m := make(map[int]int)
	nn := make([]int, 0)
	for _, v := range slice1 {
		m[v]++
	}

	for _, v := range slice2 {
		times, _ := m[v]
		if times == 1 {
			nn = append(nn, v)
		}
	}
	return nn
}

// 求差集 slice1-并集
func DifferenceForInt(slice1, slice2 []int) []int {
	m := make(map[int]int)
	nn := make([]int, 0)
	inter := IntersectForInt(slice1, slice2)
	for _, v := range inter {
		m[v]++
	}

	for _, value := range slice1 {
		times, _ := m[value]
		if times == 0 {
			nn = append(nn, value)
		}
	}
	return nn
}

// 求并集
func UnionForInt64(slice1, slice2 []int64) []int64 {
	m := make(map[int64]int64)
	for _, v := range slice1 {
		m[v]++
	}

	for _, v := range slice2 {
		times, _ := m[v]
		if times == 0 {
			slice1 = append(slice1, v)
		}
	}
	return slice1
}

// 求交集
func IntersectForInt64(slice1, slice2 []int64) []int64 {
	m := make(map[int64]int64)
	nn := make([]int64, 0)
	for _, v := range slice1 {
		m[v]++
	}

	for _, v := range slice2 {
		times, _ := m[v]
		if times == 1 {
			nn = append(nn, v)
		}
	}
	return nn
}

// 求差集 slice1-并集
func DifferenceForInt64(slice1, slice2 []int64) []int64 {
	m := make(map[int64]int64)
	nn := make([]int64, 0)
	inter := IntersectForInt64(slice1, slice2)
	for _, v := range inter {
		m[v]++
	}

	for _, value := range slice1 {
		times, _ := m[value]
		if times == 0 {
			nn = append(nn, value)
		}
	}
	return nn
}

// Contains 判断元素是否存在
// ps: go 中的 == 比较的是值是否相等；如果要比较对象是指针，比较的是内存地址
func Contains(array interface{}, val interface{}) (index bool) {
	index = false
	switch reflect.TypeOf(array).Kind() {
	case reflect.Slice:
		{
			s := reflect.ValueOf(array)
			for i := 0; i < s.Len(); i++ {
				if reflect.DeepEqual(val, s.Index(i).Interface()) {
					index = true
					return
				}
			}
		}
	}
	return
}

// RemoveElementFast 交换并截断（不保持顺序，但更快）
// slice := []string{"a", "b", "c", "b", "d"}
// slice = RemoveElementFast(slice, "b") // 删除所有"b"
func RemoveElementFast(slice []string, target string) []string {
	for i := 0; i < len(slice); i++ {
		if slice[i] == target {
			slice[i] = slice[len(slice)-1] // 用最后一个元素替换
			slice = slice[:len(slice)-1]   // 截断最后一个元素
			i--                            // 重新检查当前位置
		}
	}
	return slice
}

// RemoveElement 使用 append 和重新切片（保持顺序）
// slice := []string{"a", "b", "c", "b", "d"}
// slice = RemoveElement(slice, "b") // 删除所有"b"
func RemoveElement(slice []string, target string) []string {
	result := slice[:0] // 重用底层数组
	for _, v := range slice {
		if v != target {
			result = append(result, v)
		}
	}
	return result
}

// GetIndexInt64Slice 获取元素在切片中的下标，不存在就返回 -1
func GetIndexInt64Slice(element int64, array []int64) int {
	for i := range array {
		if array[i] == element {
			return i
		}
	}
	return -1
}

// GetIndexStringSlice 获取元素在切片中的下标，不存在就返回 -1
func GetIndexStringSlice(element string, array []string) int {
	for i := range array {
		if array[i] == element {
			return i
		}
	}
	return -1
}
